package com.example.demo.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @description:
 * @author: cj
 * @create: 08-12-22 08:56:23
 */
@Component
public class JwtUtil {
    //密钥
    @Value("${jwt.token-secret}")
    private String TOKEN_SECRET;


    //30分钟超时

    //    private static final long TIME_OUT = 30 * 60 * 1000;
    @Value("${jwt.token-expiration-time}")
    private String TIME_OUT;

    //加密
    public String sign(String user) {
        try {
            Date expiration_time = new Date( System.currentTimeMillis() + Integer.parseInt( TIME_OUT ) );
            Algorithm algorithm = Algorithm.HMAC256( TOKEN_SECRET );
            Map<String, Object> headerMap = new HashMap<>( 2 );
            headerMap.put( "type", "JWT" );
            headerMap.put( "alg", "HS256" );
            return JWT.create().withHeader( headerMap ).withClaim( "user", user ).withExpiresAt( expiration_time ).sign( algorithm );
        } catch (Exception e) {
            return null;
        }
    }

    public static boolean verifyToken(String token, String key) {
        try {
            JWTVerifier verifier = JWT.require( Algorithm.HMAC256( key ) )
                    .build();
            DecodedJWT jwt = verifier.verify( token );
            Map<String, Claim> claims = jwt.getClaims();

            return true;
        } catch (Exception e) {
            return false;
        }
    }

    //解密
    public DecodedJWT verify(String token) {
        try {
            JWTVerifier verifier = JWT.require( Algorithm.HMAC256( TOKEN_SECRET ) ).build();
            DecodedJWT jwt = verifier.verify( token );
            return jwt;
        } catch (Exception e) {
            //解码异常
            return null;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public String getUsername(String token) {
        try {
            DecodedJWT jwt = JWT.decode( token );
            return jwt.getClaim( "aaa" ).asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    public static void main(String[] args) {
        JwtUtil jwtUtil = new JwtUtil();
        String key = "5R5roUcuAu3o5C3o";
        String token = jwtUtil.sign( "170L" );
        token = "eyJ0eXBlIjoiSldUIiwiYWxnIjoiSFMyNTYiLCJ0eXAiOiJKV1QifQ.eyJ1aWQiOiJ7XCJfaWRcIjp7XCJkYXRlXCI6MTY0MDE1NTQxNzAwMCxcInRpbWVzdGFtcFwiOjE2NDAxNTU0MTd9LFwiYWNjb3VudFwiOlwiMTIzNDU2Nzg5MDRcIixcInBhc3N3b3JkXCI6XCIyMDJjYjk2MmFjNTkwNzViOTY0YjA3MTUyZDIzNGI3MFwifSIsImV4cCI6MTY0MDIyNTA0MH0.ttHOsjgPKI9wfaEavMijv-z8BNHyypijyvXzDkbm9C8";
        boolean b = verifyToken( token, key );
        System.out.println( b );
        System.out.println( "token::" + token );
        DecodedJWT jwt = jwtUtil.verify( token );
        if (jwt != null) {
            //UID
            System.out.println( "uid::" + jwt.getClaim( "uid" ).asLong() );
            //TIMEOUT
            System.out.println( "timeout::" + jwt.getExpiresAt() );
            //ALG
            System.out.println( "alg::" + jwt.getAlgorithm() );
            //TOKEN
            System.out.println( "token::" + jwt.getToken() );
            //HEADER
            System.out.println( "header::" + jwt.getHeader() );
            //PAYLOAD
            System.out.println( "payload::" + jwt.getPayload() );
            //SIGNATURE
            System.out.println( "signature::" + jwt.getSignature() );
        } else {
            System.out.println( "Decoded JWT Failure" );
        }
    }
}
